package org.vs.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.data.redis.core.RedisTemplate;
import org.vs.constant.RedisConstant;
import org.vs.constant.UserConstant;
import org.vs.domain.dto.LoginDTO;
import org.vs.domain.model.SysUser;
import org.vs.result.RestResult;
import org.vs.result.RestResultBuilder;
import org.vs.service.SysUserService;
import org.vs.mapper.SysUserMapper;
import org.springframework.stereotype.Service;
import org.vs.util.JwtUtil;
import org.vs.util.StringUtil;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.WalletUtils;

import javax.annotation.Resource;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Fall
 * @description 针对表【sys_user】的数据库操作Service实现
 * @createDate 2023-12-24 21:10:31
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser>
        implements SysUserService {

    @Resource
    private SysUserMapper userMapper;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource(name = "credential-address")
    private String credentialAddress;

    @Override
    public RestResult login(LoginDTO loginDTO) {
        if (loginDTO == null ||
                loginDTO.getUsername() == null ||
                loginDTO.getUsername() == null) {
            return new RestResultBuilder().failIncompleteData();
        }

        SysUser user = userMapper.selectOne(
                new QueryWrapper<SysUser>().eq("username", loginDTO.getUsername()));

        String token = (String) redisTemplate.opsForValue().get(RedisConstant.USER_REDIS_TOKEN_KEY + user.getUserId());

        if (token != null) {
            return new RestResultBuilder().success((Object) token);
        }

        if (user == null) {
            return new RestResultBuilder().fail("查无此人");
        }

        try {
            StringBuffer credentialsJson = new StringBuffer();

            InputStream inputStream =
                    new URL(StringUtil.getFilePathInServer(credentialAddress, user.getWalletUrl())).openStream();

            int temp;
            while ((temp = inputStream.read()) != -1) {
                credentialsJson.append((char) temp);
            }

            Credentials credentials = WalletUtils.loadJsonCredentials(loginDTO.getPassword(),
                    credentialsJson.toString());

            token = JwtUtil.getToken(user);

            redisTemplate.opsForValue().set(RedisConstant.USER_REDIS_TOKEN_KEY + user.getUserId(),
                    token,
                    UserConstant.LOGIN_TIME,
                    TimeUnit.MILLISECONDS);
            redisTemplate.opsForValue().set(RedisConstant.USER_REDIS_CREDENTIAL_KEY + user.getUserId(),
                    JSON.toJSONString(credentials),
                    UserConstant.LOGIN_TIME,
                    TimeUnit.MILLISECONDS);

            return new RestResultBuilder().success((Object) token);
        } catch (Exception e) {
            log.error("加载钱包失败 {}", e);
            return new RestResultBuilder().fail("加载钱包失败");
        }
    }

    @Override
    public RestResult info(String token) {
        SysUser sysUser = JwtUtil.getUser(token);

        sysUser = userMapper.selectById(sysUser.getUserId());
        sysUser.setWalletUrl("");

        return new RestResultBuilder().success(sysUser);
    }

    @Override
    public RestResult all() {
        List<SysUser> users = userMapper.selectList(new QueryWrapper<>());
        return new RestResultBuilder().success(users);
    }
}




